package com.accesshollywood.prefs;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.lang.reflect.Field;
import java.util.EnumSet;
import java.util.Scanner;

import com.accesshollywood.advDatatypes.BoundedInt;
import com.accesshollywood.trace.Trace;

public class Prefs {
	public static class PixelSize {
		public static BoundedInt	borderLR		= new BoundedInt(2, 0, 10);
		public static BoundedInt	borderTB		= new BoundedInt(2, 0, 10);
		public static BoundedInt	deadline		= new BoundedInt(11, 8, 30);
		public static BoundedInt	block			= new BoundedInt(15, 8, 30);
		public static BoundedInt	graphicType		= new BoundedInt(13, 8, 30);
		public static BoundedInt	destination		= new BoundedInt(13, 8, 30);
		public static BoundedInt	summary			= new BoundedInt(13, 8, 30);
		public static BoundedInt	show			= new BoundedInt(9, 8, 30);
		public static BoundedInt	orderNum		= new BoundedInt(15, 8, 30);
		public static BoundedInt	textList		= new BoundedInt(24, 8, 30);
		public static BoundedInt	stillList		= new BoundedInt(13, 8, 30);
		public static BoundedInt	footageList		= new BoundedInt(13, 8, 30);
		public static BoundedInt	notes			= new BoundedInt(11, 8, 30);
		public static BoundedInt	preApprovedList	= new BoundedInt(24, 8, 30);
	}

	public static class Notifications {
		public static enum NotifyType {
			EMAIL,
			SPEAK,
			CHIME
		}

		public static EnumSet<NotifyType>	orderAssigned		= EnumSet.of(Notifications.NotifyType.EMAIL);
		public static EnumSet<NotifyType>	orderUnassigned		= EnumSet.noneOf(Notifications.NotifyType.class);
		public static EnumSet<NotifyType>	orderModified		= EnumSet.noneOf(Notifications.NotifyType.class);
		public static EnumSet<NotifyType>	textEdited			= EnumSet.noneOf(Notifications.NotifyType.class);
		public static EnumSet<NotifyType>	photosChanged		= EnumSet.noneOf(Notifications.NotifyType.class);
		public static EnumSet<NotifyType>	footageChanged		= EnumSet.noneOf(Notifications.NotifyType.class);
		public static EnumSet<NotifyType>	deadlineChanged		= EnumSet.noneOf(Notifications.NotifyType.class);
		public static EnumSet<NotifyType>	deadlineApproaching	= EnumSet.noneOf(Notifications.NotifyType.class);
		public static EnumSet<NotifyType>	notesChanged		= EnumSet.noneOf(Notifications.NotifyType.class);
		public static EnumSet<NotifyType>	researchApproved	= EnumSet.noneOf(Notifications.NotifyType.class);
		public static EnumSet<NotifyType>	photoEditApproved	= EnumSet.noneOf(Notifications.NotifyType.class);
		public static EnumSet<NotifyType>	footageApproved		= EnumSet.noneOf(Notifications.NotifyType.class);
		public static EnumSet<NotifyType>	legalApproved		= EnumSet.noneOf(Notifications.NotifyType.class);
		public static EnumSet<NotifyType>	markedComplete		= EnumSet.noneOf(Notifications.NotifyType.class);
		public static EnumSet<NotifyType>	orderClosed			= EnumSet.noneOf(Notifications.NotifyType.class);
		public static EnumSet<NotifyType>	orderReopened		= EnumSet.noneOf(Notifications.NotifyType.class);
		public static EnumSet<NotifyType>	orderArchived		= EnumSet.noneOf(Notifications.NotifyType.class);
		public static EnumSet<NotifyType>	orderUnArchived		= EnumSet.noneOf(Notifications.NotifyType.class);

	}

	public static void setDefaults() {
		PixelSize.deadline.set(11);
		PixelSize.block.set(15);
		PixelSize.graphicType.set(13);
		PixelSize.destination.set(13);
		PixelSize.summary.set(13);
		PixelSize.show.set(9);
		PixelSize.orderNum.set(15);
		PixelSize.textList.set(24);
		PixelSize.stillList.set(13);
		PixelSize.footageList.set(13);
		PixelSize.notes.set(11);
		PixelSize.preApprovedList.set(24);
		Notifications.orderAssigned = EnumSet.noneOf(Notifications.NotifyType.class);
		Notifications.orderUnassigned = EnumSet.noneOf(Notifications.NotifyType.class);
		Notifications.orderModified = EnumSet.noneOf(Notifications.NotifyType.class);
		Notifications.textEdited = EnumSet.noneOf(Notifications.NotifyType.class);
		Notifications.photosChanged = EnumSet.noneOf(Notifications.NotifyType.class);
		Notifications.footageChanged = EnumSet.noneOf(Notifications.NotifyType.class);
		Notifications.deadlineChanged = EnumSet.noneOf(Notifications.NotifyType.class);
		Notifications.deadlineApproaching = EnumSet.noneOf(Notifications.NotifyType.class);
		Notifications.notesChanged = EnumSet.noneOf(Notifications.NotifyType.class);
		Notifications.researchApproved = EnumSet.noneOf(Notifications.NotifyType.class);
		Notifications.photoEditApproved = EnumSet.noneOf(Notifications.NotifyType.class);
		Notifications.footageApproved = EnumSet.noneOf(Notifications.NotifyType.class);
		Notifications.legalApproved = EnumSet.noneOf(Notifications.NotifyType.class);
		Notifications.markedComplete = EnumSet.noneOf(Notifications.NotifyType.class);
		Notifications.orderClosed = EnumSet.noneOf(Notifications.NotifyType.class);
		Notifications.orderReopened = EnumSet.noneOf(Notifications.NotifyType.class);
		Notifications.orderArchived = EnumSet.noneOf(Notifications.NotifyType.class);
		Notifications.orderUnArchived = EnumSet.noneOf(Notifications.NotifyType.class);
	}

	public static void save() {
		String NL = System.getProperty("line.separator");
		try {
			File prefs = new File("prefs.txt");
			Trace.info(prefs.getAbsolutePath());
			Writer out = new OutputStreamWriter(new FileOutputStream("prefs.txt"));
			// ---------------------//

			Class<?>[] innerClasses = Prefs.class.getDeclaredClasses();

			for (Class currClass : innerClasses) {
				String name = currClass.getSimpleName();
				String name2 = currClass.getName();
				out.write("CLASS" + NL);
				out.write(name2 + NL);
				Trace.info(name2);

				Field[] fields = currClass.getFields();

				int count = 0;
				for (Field currField : fields) {
					out.write("FIELD" + NL);
					out.append(currField.getName() + NL);
					out.append(currField.get(Prefs.class).toString() + NL);
					Trace.info(currField.getName());
					Trace.info(currField.get(Prefs.class).toString());

					if (currField.getType().equals(BoundedInt.class)) {

					} else if (currField.getType().equals(EnumSet.class)) {

					}
					count++;
				}
			}

			out.close();

			// ---------------------//
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	@SuppressWarnings({ "static-access", "rawtypes" })
	public static void load() {
		Class c = null;
		Field f = null;
		String nextLine;

		try {
			Scanner scanner = new Scanner(new FileInputStream("prefs.txt"));

			while (scanner.hasNextLine()) {
				nextLine = scanner.nextLine();
				Trace.info(nextLine);
				if (nextLine.equals("CLASS")) {
					nextLine = scanner.nextLine();
					String className = nextLine;
					c = Class.forName(className);
				} else if (nextLine.equals("FIELD")) {
					nextLine = scanner.nextLine();
					f = c.getField(nextLine);
					nextLine = scanner.nextLine();
					if (f.getType().equals(BoundedInt.class)) {
						BoundedInt v = (BoundedInt) f.get(c);
						v.set(Integer.parseInt(nextLine));
						f.set(c, v);
					} else if (f.getType().equals(EnumSet.class)) {

						Class[] enumClasses = c.getClasses();
						Object[] prefSettings = null;
						Class enumClass = null;
						for (int i = 0; i < enumClasses.length; i++) {
							if (enumClasses[i].isEnum()) {
								prefSettings = enumClasses[i].getDeclaredFields();
								enumClass = enumClasses[i];
								break;
							}
						}
						if (enumClass != null) {
							EnumSet v = EnumSet.noneOf(enumClass);// (EnumSet)f.get(c);
							v = getEnumSetByValue(enumClass, nextLine);
							f.set(c, v);
							Trace.info(f.toString());
							Trace.info(Prefs.Notifications.orderAssigned);
						}
					}
				}

			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static EnumSet getEnumSetByValue(Class enumClass, String value) {
		EnumSet returnSet = EnumSet.noneOf(enumClass);
		if (!value.equals("[]")) {
			String s1 = value.split("\\[")[1];
			String s2 = s1.split("\\]")[0];
			String[] s3 = s2.split("\\,");

			Enum[] possible = (Enum[]) enumClass.getEnumConstants();

			for (String str : s3) {
				for (Enum currEnum : possible) {
					Trace.info(str.trim() + "   " + currEnum.name().trim());
					if (str.trim().equals(currEnum.name().trim())) {
						returnSet.add(currEnum);
						Trace.info(returnSet.toString());
						break;
					}
				}
			}
		}
		Trace.info(returnSet.toString());
		return returnSet;
	}
}
